function [U,Z,Ap,alpha,obj] = LASD(X,numclass,numanchor,gamma,eta)
% LASD Algorithm
% Implicitly Aligned Multi-view Clustering with Quadratic Cost Optimal Transport
% Xp:dp*n v, C:n*m*v, Ap:dp*m v, alpha:1*1*v, Zp:n*m*v, Z:n*m, miu:n*1*v, niu:1*m*v, miu0:n*1, niu0:1*m
% Note: Zp in the code corresponds to Tp in the paper.
% rng_num = 0;
stream = RandStream.getGlobalStream;
reset(stream);

numview = length(X);
numsample = size(X{1},2);

%% initialize
U = [];
for p = 1:numview
    [U0,~,~]=svds(X{p}',min(length(X{p}'),numclass));
    U = [U,U0];
end
U_normalized = U ./ repmat(sqrt(sum(U.^2, 2)), 1,size(U,2));
IDXZ = litekmeans(U_normalized,numanchor,'MaxIter',100, 'Replicates',30);

Z = zeros(numsample, numanchor);
for i = 1:numsample
    Z(i,IDXZ(i)) = 1/numsample;
end
% aa = 0.5;%原版
% Z = Z*aa + 1/numsample/numanchor*(1-aa);
aa = 0.99;%0.5
Z = Z*aa + rand(numsample, numanchor)*2/numsample/numanchor*(1-aa);
Zp = repmat(Z,1,1,numview);%
clear U0 U U_normalized IDXZ

Ap = cell(numview,1);
C = zeros(numsample,numanchor,numview);

%% Precomputation
M = ones(1,1,numview);
alpha = M / numview;

%% Preset
miu=[];
niu=[];
miu0=[];
niu0=[];

flag = 1;
iter = 0;
obj = [];
maxIter = 30; % the maximum number of iterations

%% Iteriation
while flag
    iter = iter +1
    
    % Update A^{(p)}
    for p = 1:numview
        Ap{p} = X{p} * Zp(:,:,p) * numanchor;
        C(:,:,p) = pdist2(X{p}',Ap{p}').^2;
    end
    
    % Update Z^{(p)}, Z
    [Zp,Z,miu,niu,miu0,niu0] = updateAllZ(C,gamma,eta,alpha,Zp,Z,miu,niu,miu0,niu0);
    
    % Update alpha
    for p = 1:numview
        M(p) = sum((Z-Zp(:,:,p)).^2,'all');
    end
    M_inv = 1 ./ max(M,1/numview*1e-5);%res3
%     M_inv = 1 ./ max(M,1/numview*eps);%res4
    alpha = M_inv / sum(M_inv);
    
    % Calculate obj
    obj(end+1,:) = callobj(C,Zp,Z,alpha,gamma,eta);
    
    if (iter>maxIter)&&(abs(obj(iter-1)-obj(iter))/abs(obj(2)-obj(3))<1e-3 || iter>maxIter)%iter>5
        flag = 0;
    end
end

% [U,~,~]=svd(Z,'econ');
[U,~,~]=svds(Z,numclass);

end